package com.gionee.navil.lockscreen.shortcut;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.ExifInterface;
import android.os.ParcelFileDescriptor;
import android.view.Surface;

public class Util {
    public static final int MIN_PIC_SIZE = 128;

    public static void setOrientation(Activity activity, int cameraId, Camera camera, Parameters parameters) {
//        Camera.CameraInfo info = new Camera.CameraInfo();
//        Camera.getCameraInfo(cameraId, info);
//        int degrees;
//        int result;
//        degrees = sDegree;
//        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
//            result = (info.orientation + degrees) % 360;
//            result = (360 - result) % 360;
//        } else { // back-facing
//            result = (info.orientation - degrees + 360) % 360;
//        }
        int degrees = getDisplayRotation(activity);
        try {
            Class<?> cameraClass = Class.forName("android.hardware.Camera");
            Class<?> cameraInfoClass = Class.forName("android.hardware.Camera$CameraInfo");
            Field fieldOrientation = cameraInfoClass.getDeclaredField("orientation");
            Object info = cameraInfoClass.getConstructor(new Class[] {}).newInstance(new Object[] {});
            Method getCameraInfo = cameraClass.getMethod("getCameraInfo", Integer.TYPE, cameraInfoClass);
            getCameraInfo.invoke(null, cameraId, info);
            int orientation = fieldOrientation.getInt(info);
            int result = (orientation - degrees + 360) % 360;
            camera.setDisplayOrientation(result);
            parameters.setRotation(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void setOrientation(int cameraId, Camera camera, Parameters parameters) {
//      Camera.CameraInfo info = new Camera.CameraInfo();
//      Camera.getCameraInfo(cameraId, info);
//      int degrees;
//      int result;
//      degrees = sDegree;
//      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
//          result = (info.orientation + degrees) % 360;
//          result = (360 - result) % 360;
//      } else { // back-facing
//          result = (info.orientation - degrees + 360) % 360;
//      }
      int degrees = getDisplayRotation();
      try {
          Class<?> cameraClass = Class.forName("android.hardware.Camera");
          Class<?> cameraInfoClass = Class.forName("android.hardware.Camera$CameraInfo");
          Field fieldOrientation = cameraInfoClass.getDeclaredField("orientation");
          Object info = cameraInfoClass.getConstructor(new Class[] {}).newInstance(new Object[] {});
          Method getCameraInfo = cameraClass.getMethod("getCameraInfo", Integer.TYPE, cameraInfoClass);
          getCameraInfo.invoke(null, cameraId, info);
          int orientation = fieldOrientation.getInt(info);
          int result = (orientation - degrees + 360) % 360;
          camera.setDisplayOrientation(result);
          parameters.setRotation(result);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

    public static void closeSilently(Closeable c) {
        if (c == null)
            return;
        try {
            c.close();
        } catch (Throwable t) {
        }
    }

    public static void closeSilently(ParcelFileDescriptor c) {
        if (c == null)
            return;
        try {
            c.close();
        } catch (Throwable t) {
            // do nothing
        }
    }

    public static Bitmap getResizeBitmap(Context context, String path, int newWidth, int newHeight) {
        Bitmap bitmap = null;

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, opts);

        opts.inSampleSize = computeSampleSize(opts, -1, MIN_PIC_SIZE * MIN_PIC_SIZE);
        opts.inJustDecodeBounds = false;
        try {
            bitmap = BitmapFactory.decodeFile(path, opts);
        } catch (OutOfMemoryError err) {
        }
        Bitmap resizeBitmap = null;

        if (bitmap == null) {
            return null;
        }

        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int tag = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
            switch (tag) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
                default:
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        int resizeWidth = newWidth;
        int resizeHeight = newHeight;

        float scale;
        if (width > height) {
            scale = ((float) height) / width;
            resizeWidth = (int) (resizeHeight / scale);
        } else {
            scale = ((float) width) / height;
            resizeHeight = (int) (resizeWidth / scale);
        }

        float scaleWidth = ((float) resizeWidth) / width;
        float scaleHeight = ((float) resizeHeight) / height;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        matrix.postRotate(degree);

        resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
        }
        return resizeBitmap;
    }

    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength,
            int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? MIN_PIC_SIZE : (int) Math.min(Math.floor(w / minSideLength),
                Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    public static int getDisplayRotation(Activity activity) {
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        switch (rotation) {
            case Surface.ROTATION_0:
                return 0;
            case Surface.ROTATION_90:
                return 90;
            case Surface.ROTATION_180:
                return 180;
            case Surface.ROTATION_270:
                return 270;
        }
        return 0;
    }
    
    public static int getDisplayRotation() {
//        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
//        switch (rotation) {
//            case Surface.ROTATION_0:
//                return 0;
//            case Surface.ROTATION_90:
//                return 90;
//            case Surface.ROTATION_180:
//                return 180;
//            case Surface.ROTATION_270:
//                return 270;
//        }
        return 0;
    }

    public static int clamp(int x, int min, int max) {
        if (x > max)
            return max;
        if (x < min)
            return min;
        return x;
    }

    public static void rectFToRect(RectF rectF, Rect rect) {
        rect.left = Math.round(rectF.left);
        rect.top = Math.round(rectF.top);
        rect.right = Math.round(rectF.right);
        rect.bottom = Math.round(rectF.bottom);
    }
    
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}
